import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { CreateGradeDto, UpdateGradeDto, QueryGradeDto } from '@dto/grade.dto';
import { GradeEntity } from '@entity/grade.entity';
import { SysDept } from '@entity/framework/system/SysDept';
import { resBuild } from '../utils/resBuild';
import { getOperator, isEmpty } from '../utils';

@Provide()
export class GradeDao {
  @Inject()
  ctx: Context;
  @InjectEntityModel(GradeEntity)
  gradeEntityRep: Repository<GradeEntity>;
  @InjectEntityModel(SysDept)
  sysDeptEntityRep: Repository<SysDept>;


  async create(createGradeDto: CreateGradeDto) {
    const entity = this.gradeEntityRep.create(createGradeDto);
    entity.setCreateBy(getOperator(this.ctx));
    entity.setUpdateBy(getOperator(this.ctx));
    await this.gradeEntityRep.save(entity);
    return resBuild.success();
  }

  async list(query: QueryGradeDto) {
    const entity = this.gradeEntityRep
      .createQueryBuilder('entity')
      .where('entity.delFlag = :delFlag', { delFlag: '0' });

    if (!isEmpty(query.deptId)) {
      entity.andWhere('entity.deptId = :deptId', { deptId: query.deptId });
    }
    if (!isEmpty(query.gradeName)) {
      entity.andWhere('entity.gradeName = :gradeName', {
        gradeName: query.gradeName,
      });
    }
    if (!isEmpty(query.status)) {
      entity.andWhere('entity.status = :status', { status: query.status });
    }
    entity.select([
      'entity.gradeId',
      'entity.deptId',
      'entity.gradeName',
      'entity.remark',
      'entity.status',
    ]);
    if (query.pageNum && query.pageSize) {
      entity.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }
    entity.addOrderBy('entity.createTime', 'DESC');
    const [list, total] = await entity.getManyAndCount();
    return resBuild.list(list, total);
  }

  async detail(gradeId: number) {
    const detailInfo = await this.gradeEntityRep.findOneBy({ gradeId });
    return resBuild.data(detailInfo);
  }

  async update(updateGradeDto: UpdateGradeDto) {
    const entity = this.gradeEntityRep.create(updateGradeDto);
    entity.setUpdateBy(getOperator(this.ctx));
    await this.gradeEntityRep.save(entity);
    return resBuild.success();
  }

  async remove(gradeIds: Array<number>) {
    await this.gradeEntityRep.update(
      { gradeId: In(gradeIds) },
      {
        delFlag: '1',
        updateBy: getOperator(this.ctx),
        updateTime: new Date(),
      }
    );
    return resBuild.success();
  }
  //学院年级树
  async tree() {
    const list = await this.sysDeptEntityRep
      .createQueryBuilder('entity')
      .where('entity.delFlag = :delFlag', { delFlag: '0' })
      .andWhere('entity.deptName LIKE :deptName', { deptName: `%学院%` })
      .leftJoinAndSelect('entity.children', 'children', 'children.delFlag = :childDelFlag', { childDelFlag: '0' })
      .leftJoinAndSelect('children.children', 'childrenChildren', 'childrenChildren.delFlag = :childChildDelFlag', { childChildDelFlag: '0' })
      .select([
        'entity.deptId',
        'entity.deptName',
        'children.gradeId',
        'children.gradeName',
        'children.deptId',
        'childrenChildren.majorId',
        'childrenChildren.majorName',
        'childrenChildren.gradeId',
      ])
      .getMany();
    return resBuild.data(list);
  }
}
